package com.caijin.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.caijin.common.core.domain.Result;
import com.caijin.common.core.domain.dto.ClazzDTO;
import com.caijin.common.core.domain.entity.Clazz;
import com.caijin.common.core.domain.entity.Course;
import com.caijin.common.core.domain.entity.Student;
import com.caijin.common.core.domain.vo.ClazzVO;
import com.caijin.common.enums.ResultCode;
import com.caijin.system.entity.StudentClazz;
import com.caijin.system.mapper.ClazzMapper;
import com.caijin.system.mapper.StudentClazzMapper;
import com.caijin.system.service.IClazzService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.caijin.system.service.IStudentClazzService;
import com.caijin.system.service.IStudentService;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * <p>
 * 班级表 服务实现类
 * </p>
 *
 * @author Peas
 * @since 2021-01-18
 */
@Service
@Transactional
public class ClazzServiceImpl extends ServiceImpl<ClazzMapper, Clazz> implements IClazzService {

    @Autowired
    private ClazzMapper mapper;

    @Autowired
    private StudentClazzMapper studentClazzMapper;

    @Autowired
    private IStudentClazzService studentClazzService;

    @Autowired
    private IStudentService studentService;

    /**
     * 创建班级
     *
     * @param clazz 班级信息,附带有cno
     * @return 结果
     */
    @Override
    public Result createClazz(Clazz clazz) {
        Boolean exists = this.clazzNameExists(clazz);
        if (!exists) {
            this.mapper.insert(clazz);
            Long l = System.currentTimeMillis() + 3600L * 1000 * 24 * 365 + clazz.getId();
            clazz.setInvitationCode(l + "");
            int i = this.mapper.updateById(clazz);
            return i != 0 ? Result.ok() : Result.error();
        } else {
            return Result
                    .error()
                    .message(ResultCode.CLAZZ_NAME_EXISTS.getMessage())
                    .code(ResultCode.CLAZZ_NAME_EXISTS.getCode());
        }
    }

    /**
     * 学生加入班级
     *
     * @param invitationCode 邀请码
     * @param sno            学号
     * @return
     */
    @Override
    public Result joinClazz(String invitationCode, Long sno) {
        Result result = new Result();
        QueryWrapper<Clazz> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("invitation_code", invitationCode);
        Clazz clazz = this.mapper.selectOne(queryWrapper);
        if (clazz != null) {
            List<Course> courseListBySno = studentClazzMapper.getCourseListBySno(sno);
            for (Course course : courseListBySno) {
                if (course.getCno().equals(clazz.getCno()))
                    return result.code(ResultCode.USER_ALREADY_EXISTS_IN_THE_COURSE.getCode()).message(ResultCode.USER_ALREADY_EXISTS_IN_THE_COURSE.getMessage()).success(false);
            }
            StudentClazz studentClazz = new StudentClazz();
            studentClazz.setClazzId(clazz.getId());
            studentClazz.setSno(sno);
            return studentClazzService.joinClazz(studentClazz);
        }
        result.code(ResultCode.CLAZZ_NOT_EXISTS.getCode()).message(ResultCode.CLAZZ_NOT_EXISTS.getMessage()).success(false);
        return result;
    }

    /**
     * 获取课程的班级列表
     *
     * @param cno 课程号
     * @return 班级列表
     */
    @Override
    public Result getClazzListByCno(Long cno) {
        QueryWrapper<ClazzVO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("cno", cno);
        List<ClazzVO> clazzVOS = this.mapper.getClazzListWithSNum(queryWrapper);
        return clazzVOS != null ? Result.ok().data("clazzList", clazzVOS) : Result.error();
    }

    /**
     * 获取班级的学生列表
     *
     * @param clazzId 班级id
     * @return 学生列表
     */
    @Override
    public Result getStudentList(Long clazzId) {
        QueryWrapper<StudentClazz> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("clazz_id", clazzId);

        List<Student> collect = studentClazzService.getBaseMapper().selectList(queryWrapper).stream().map(o -> {
            return studentService.getById(o.getSno());
        }).collect(Collectors.toList());
        return collect != null ? Result.ok().data("studentList", collect) : Result.error();
    }

    /**
     * 修改班级信息
     *
     * @param clazzDTO 班级修改信息传递模型
     * @return
     */
    @Override
    public Result modifiedClazz(ClazzDTO clazzDTO) {
        Clazz clazz = this.mapper.selectOne(new QueryWrapper<Clazz>().eq("id", clazzDTO.getId()));
        clazz.setName(clazzDTO.getName());
        Boolean exists = this.clazzNameExists(clazz);
        if (!exists) {
            int i = this.mapper.updateById(clazz);
            return i != 0 ? Result.ok() : Result.error();
        } else {
            return Result
                    .error()
                    .message(ResultCode.CLAZZ_NAME_EXISTS.getMessage())
                    .code(ResultCode.CLAZZ_NAME_EXISTS.getCode());
        }
    }

    /**
     * 删除班级
     *
     * @param id 班级id
     * @return 结果
     */
    @Override
    public Result deleteClazz(Long id) {
        int i = this.mapper.deleteById(id);
        return i != 0 ? Result.ok() : Result.error();
    }

    /**
     * 判断班级名称是否重复
     *
     * @param clazz 班级对象
     * @return
     */
    private Boolean clazzNameExists(Clazz clazz) {
        QueryWrapper<Clazz> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", clazz.getName()).and(i -> i.eq("cno", clazz.getCno()));
        Clazz clazz1 = this.mapper.selectOne(queryWrapper);
        if (clazz1 == null) return false;
        else return true;
    }
}
